#pragma once
#include <variant>
#include <string>
#include <vector>
#include <map>

namespace imitation
{
    namespace json
    {

        class Json
        {
        public:
            enum Type
            {
                json_num = 0,
                json_null,
                json_bool,
                json_int,
                json_double,
                json_string,
                json_array,
                json_object
            };
            Json();
            Json(const bool value);
            Json(const int value);
            Json(const double value);
            Json(const char * value);
            Json(const std::string & value);
            Json(const std::vector<Json> & value);
            Json(const std::map<std::string, Json> & value);
            Json(Type type);
            Json(const Json &value);
            Json & operator=(const Json & value);

            operator bool() const;
            operator int() const;
            operator double() const;
            operator std::string() const;
            bool operator == (const Json &value) const;
            bool operator!= (const Json &value) const;
            bool is_null() const;
            bool is_bool() const;
            bool is_int() const;
            bool is_double() const;
            bool is_string() const;
            bool is_array() const;
            bool is_object() const;
            bool as_bool() const;
            int as_int() const;
            double as_double() const;
            std::string as_string() const;
            std::vector<Json> as_array() const;
            std::map<std::string, Json> as_object() const;
            bool has(const std::string &key) const;
            bool has(const char *key) const;
            bool has(int index) const;
            void remove(const std::string &key);
            void remove(const char *key);
            void remove(int index);
            
            //数组接口
            Json &operator[](int i);
            void append(const Json &value);
            //可以再写一个pop
            std::string str() const;
            //对象接口
            Json &operator[](const std::string &key);
            Json &operator[](const char *key);

            void parse(const std::string &json);

        private:
            std::variant<
                std::monostate,
                bool,
                int,
                double,
                std::string,
                std::vector<Json>,
                std::map<std::string, Json>
                > inner;
            
            Type json_type;
        };
    }
}